#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ext2fs/ext2fs.h>
#define BLOCK_SIZE 1024 
#define FILE_SIZE 1024*1024
#define FILE_TYPE_DIR 2
#define FILE_TYPE_FILE 1

void read_node_data(char* buffer,int inodeno,int file_type);

void print_file(char* base ,int block){
	char* buffer=base+BLOCK_SIZE*block;
	buffer[1024]='\0';
	printf("file content:%s\n",buffer);
}

void print_dir(char* base,int block,struct ext2_inode* node){
	printf("begin print_dir block: %d\n\n",block);
	struct ext2_dir_entry_2* en=(struct ext2_dir_entry_2*)(base+BLOCK_SIZE*block);
	printf("read block:%d\n",block);
	int i;
	char* tmp=(char*)en;
	for(i=0;i<node->i_links_count;i++){
		printf("node info:inode=%d,rec_len=%d,name_len=%d,name=%s\n",en->inode,en->rec_len,en->name_len,en->name);
		if(en->rec_len==BLOCK_SIZE || en->rec_len==0)break;
		if(en->name[0]!='.' || en->inode<2){
			read_node_data(base,(int)en->inode,(int)en->file_type);
		}
		tmp+=en->rec_len;
		if(en->rec_len-en->name_len-8>100)break;
		en=(struct ext2_dir_entry_2*)tmp;
	}

	printf("finish print_dir block: %d\n\n",block);
}

void read_node_data(char* buffer,int inodeno,int file_type){
	printf("begin read_node_data %d\n\n",inodeno);
	printf("file type is :%d\n",file_type);
	if(inodeno>BLOCK_SIZE || inodeno<=0){
		printf("inodeno error \n");
		return;
	}
	struct ext2_inode *node=(struct ext2_inode*)(buffer+BLOCK_SIZE*8+128*inodeno);
//	printf("read inode at %d\n",(int)((char*)node-(char*)buffer));
	printf("read inode %d at %d,block count:%d,filesize:%d,link count:%d\n",inodeno,(int)((char*)node-(char*)buffer),node->i_blocks,node->i_size,node->i_links_count);
	int i=0;
	for(i=0;i<node->i_blocks;i++){
		printf("block %d: %d\n",i,node->i_block[i]);
		if(node->i_block[i]==0)continue;
		switch(file_type){
			case FILE_TYPE_DIR:
				print_dir(buffer,node->i_block[i],node);
				break;
			case FILE_TYPE_FILE:
				print_file(buffer,node->i_block[i]);//,node->i_size);
			default:
				break;
		}
	}
	printf("finish read_node_data %d\n\n",inodeno);
}



int main(){
	char* fn="ext2img";

	char buffer[FILE_SIZE];
	int n;
	int fd=open(fn,O_RDONLY);
	if(fd<0){
		perror("open file error");
		exit(1);
	}
	n=read(fd,buffer,FILE_SIZE);
	printf("read byte:%d\n",n);
	close(fn);

	struct ext2_super_block *sp;
	sp=(struct ext2_super_block*)(buffer+BLOCK_SIZE);
	char * next=(char*)(sp+sizeof(struct ext2_super_block));
	printf("size of super:%d\n",sizeof(struct ext2_super_block));
	
	struct ext2_group_desc* desc=(struct ext2_group_desc*)(buffer+BLOCK_SIZE*2);

	printf("size of desc:%d\n",sizeof(struct ext2_group_desc));
	printf("read desc: block bitmap=%d,inode_bitmat=%d,inode_table=%d,blocks_count=%d,inodes_count=%d,dirs_count=%d\n",desc->bg_block_bitmap,desc->bg_inode_bitmap,desc->bg_inode_table,desc->bg_free_blocks_count,desc->bg_free_inodes_count,desc->bg_used_dirs_count);

	printf("size of inode:%d\n",sizeof(struct ext2_inode));
	int index=1;
	read_node_data(buffer,1,FILE_TYPE_DIR);

	printf("finish\n");
}
